﻿/*
   Copyright 2012 University of Southampton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace uk.ac.soton.ses
{
    class ExperimentDataFileMetadataContainerFileSystem:ExperimentDataFileMetadataContainer
    {
        public ExperimentDataFileMetadataContainerFileSystem(ExperimentDataFileBO experimentDataFile, ExperimentMetadataContainerFileSystem parentExperimentMetadata)
            : base(experimentDataFile, parentExperimentMetadata)
        {
        }

        public override void DeleteExperimentDataFile()
        {
            string path = base.ExperimentDataFile.FullPath;

            if (!File.Exists(path))
            {
                throw new FileNotFoundException("Could not delete file as it doesn't exist", base.ExperimentDataFile.FullPath);
            }

            File.Delete(path);
            base.DeleteExperimentDataFile();
        }

        public override void RenameExperimentDataFile(string newName, string newExperimentBasePath)
        {
            string oldPath = base.ExperimentDataFile.FullPath;
            string newPath = Path.Combine(newExperimentBasePath,newName);

            if (!File.Exists(oldPath))
            {
                throw new FileNotFoundException("Could not rename file as it doesn't exist", oldPath);
            }

            if(File.Exists(newPath))
            {
                throw new NotSupportedException(string.Format("Could not rename file {0} as the new name already exists", newPath));
            }

            File.Move(oldPath, newPath);
            base.RenameExperimentDataFile(newName, newExperimentBasePath);
        }

        public override void UpdateExperimentDataFile(ExperimentDataFileBO updatedExperiment)
        {
            ExperimentMetadataContainerFileSystem parentExperiment = this._parentExperiment as ExperimentMetadataContainerFileSystem;
            if (parentExperiment != null)
            {
                this.SetFileData(updatedExperiment);
                this._experimentDataFile = parentExperiment.GetBODataFromFile(this._experimentDataFile.GetFullPath());
            }
            else
            {
                throw new ExperimentMetadataContainerException(string.Format("Not able to find valid parent experiment for file {0}", this._experimentDataFile.GetFullPath()));
            }
        }

        public void SetFileData(ExperimentDataFileBO experimentDataFile)
        {
            string filePath = this._experimentDataFile.GetFullPath();
            FileInfo fileinfo = new FileInfo(filePath);
            FileSecurity fileSecurity = fileinfo.GetAccessControl();
            fileSecurity.SetOwner(new SecurityIdentifier(experimentDataFile.FileSystemUserID));
            fileinfo.SetAccessControl(fileSecurity);
            File.SetCreationTime(filePath, experimentDataFile.CreationTime);
            File.SetLastWriteTime(filePath, experimentDataFile.LastWriteTime);
            File.SetLastAccessTime(filePath, experimentDataFile.LastAccessTime);
        }
        public override ExperimentDataFileMetadataContainer Copy()
        {
            ExperimentDataFileMetadataContainerFileSystem newContainer = new ExperimentDataFileMetadataContainerFileSystem(this._experimentDataFile, (ExperimentMetadataContainerFileSystem)base._parentExperiment);
            return newContainer;
        }

    }
}
